001    /*
002     * BasicScoringScheme.java
003     *
004     * Copyright 2003 Sergio Anibal de Carvalho Junior
005     *
006     * This file is part of NeoBio.
007     *
008     * NeoBio is free software; you can redistribute it and/or modify it under the terms of
009     * the GNU General Public License as published by the Free Software Foundation; either
010     * version 2 of the License, or (at your option) any later version.
011     *
012     * NeoBio is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
013     * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
014     * PURPOSE. See the GNU General Public License for more details.
015     *
016     * You should have received a copy of the GNU General Public License along with NeoBio;
017     * if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
018     * Boston, MA 02111-1307, USA.
019     *
020     * Proper attribution of the author as the source of the software would be appreciated.
021     *
022     * Sergio Anibal de Carvalho Junior             mailto:sergioanibaljr@users.sourceforge.net
023     * Department of Computer Science               http://www.dcs.kcl.ac.uk
024     * King's College London, UK                    http://www.kcl.ac.uk
025     *
026     * Please visit http://neobio.sourceforge.net
027     *
028     * This project was supervised by Professor Maxime Crochemore.
029     *
030     */
031    
032    package neobio.alignment;
033    
034    /**
035     * This class implements a basic scoring scheme. At least three parameters must be
036     * provided to the constructor: the reward for a match (a substitution of equal
037     * characters), the penalty for a mismatch (a substitution of different characters) and
038     * the cost of a gap (an insertion or deletion of a character). Note that it only supports
039     * an additive gap cost function.
040     *
041     * <P>Although the match reward is expected to be a positive value, and the mismatch
042     * penalty and the gap cost are expected to be negative, no attempt is made to enforce
043     * these behaviour.</P>
044     *
045     * @author Sergio A. de Carvalho Jr.
046     */
047    public class BasicScoringScheme extends ScoringScheme
048    {
049            /**
050             * The reward for a match (a substitution of equal characters).
051             */
052            protected int match_reward;
053    
054            /**
055             * The penalty for a mismatch (a substitution of different characters).
056             */
057            protected int mismatch_penalty;
058    
059            /**
060             * The cost of a gap (an insertion or deletion of a character).
061             */
062            protected int gap_cost;
063    
064            /**
065             * The maximum absolute score that this scoring scheme can return, which is the
066             * maximum absolute value among <CODE>match_reward</CODE>,
067             * <CODE>mismatch_penalty</CODE> and <CODE>gap_cost</CODE>.
068             */
069            protected int max_absolute_score;
070    
071            /**
072             * Creates a new instance of a basic scoring scheme with the specified values of
073             * match reward, mismatch penalty and gap cost. The case of characters is significant
074             * when subsequently computing their score.
075             *
076             * @param match_reward reward for a substitution of equal characters
077             * @param mismatch_penalty penalty for a substitution of different characters
078             * @param gap_cost cost of an insertion or deletion of any character
079             */
080            public BasicScoringScheme (int match_reward, int mismatch_penalty, int gap_cost)
081            {
082                    this (match_reward, mismatch_penalty, gap_cost, true);
083            }
084    
085            /**
086             * Creates a new instance of basic scoring scheme with the specified values of
087             * match reward, mismatch penalty and gap cost. If <CODE>case_sensitive</CODE> is
088             * <CODE>true</CODE>, the case of characters is significant when subsequently
089             * computing their score; otherwise the case is ignored.
090             *
091             * @param match_reward reward for a substitution of equal characters
092             * @param mismatch_penalty penalty for a substitution of different characters
093             * @param gap_cost cost of an insertion or deletion of any character
094             * @param case_sensitive <CODE>true</CODE> if the case of characters must be
095             * significant, <CODE>false</CODE> otherwise
096             */
097            public BasicScoringScheme (int match_reward, int mismatch_penalty, int gap_cost,
098                                                                    boolean case_sensitive)
099            {
100                    super(case_sensitive);
101    
102                    this.match_reward = match_reward;
103                    this.mismatch_penalty = mismatch_penalty;
104                    this.gap_cost = gap_cost;
105    
106                    // store the maximum absolute score that this scoring scheme can return,
107                    // which is the maximum absolute value among match_reward, mismatch_penalty
108                    // and gap_cost
109                    if (Math.abs(match_reward) >= Math.abs(mismatch_penalty))
110                            if (Math.abs(match_reward) >= Math.abs(gap_cost))
111                                    this.max_absolute_score = Math.abs(match_reward);
112                            else
113                                    this.max_absolute_score = Math.abs(gap_cost);
114                    else
115                            if (Math.abs(mismatch_penalty) >= Math.abs(gap_cost))
116                                    this.max_absolute_score = Math.abs(mismatch_penalty);
117                            else
118                                    this.max_absolute_score = Math.abs(gap_cost);
119            }
120    
121            /**
122             * Returns the score of a substitution of character <CODE>a</CODE> for character
123             * <CODE>b</CODE> according to this scoring scheme. It is <CODE>match_reward</CODE>
124             * if <CODE>a</CODE> equals <CODE>b</CODE>, <CODE>mismatch_penalty</CODE> otherwise.
125             *
126             * @param a first character
127             * @param b second character
128             * @return <CODE>match_reward</CODE> if <CODE>a</CODE> equals <CODE>b</CODE>,
129             * <CODE>mismatch_penalty</CODE> otherwise.
130             */
131            public int scoreSubstitution (char a, char b)
132            {
133                    if (isCaseSensitive())
134                            if (a == b)
135                                    return match_reward;
136                            else
137                                    return mismatch_penalty;
138                    else
139                            if (Character.toLowerCase(a) == Character.toLowerCase(b))
140                                    return match_reward;
141                            else
142                                    return mismatch_penalty;
143            }
144    
145            /**
146             * Always returns <CODE>gap_cost</CODE> for the insertion of any character.
147             *
148             * @param a the character to be inserted
149             * @return <CODE>gap_cost</CODE>
150             */
151            public int scoreInsertion (char a)
152            {
153                    return gap_cost;
154            }
155    
156            /**
157             * Always returns <CODE>gap_cost</CODE> for the deletion of any character.
158             *
159             * @param a the character to be deleted
160             * @return <CODE>gap_cost</CODE>
161             */
162            public int scoreDeletion (char a)
163            {
164                    return gap_cost;
165            }
166    
167            /**
168             * Returns the maximum absolute score that this scoring scheme can return for any
169             * substitution, deletion or insertion, which is the maximum absolute value among
170             * <CODE>match_reward</CODE>, <CODE>mismatch_penalty</CODE> and
171             * <CODE>gap_cost</CODE>.
172             *
173             * @return the maximum absolute value among <CODE>match_reward</CODE>,
174             * <CODE>mismatch_penalty</CODE> and <CODE>gap_cost</CODE>.
175             */
176            public int maxAbsoluteScore ()
177            {
178                    return max_absolute_score;
179            }
180    
181            /**
182             * Tells whether this scoring scheme supports partial matches, which it does not.
183             *
184             * @return always return <CODE>false</CODE>
185             */
186            public boolean isPartialMatchSupported ()
187            {
188                    return false;
189            }
190    
191            /**
192             * Returns a String representation of this scoring scheme.
193             *
194             * @return a String representation of this scoring scheme
195             */
196            public String toString ()
197            {
198                    return "Basic scoring scheme: match reward = " + match_reward +
199                    ", mismatch penalty = " + mismatch_penalty + ", gap cost = " + gap_cost;
200            }
201    }